#ifndef __RAND_EMBEDDING_ENGINE_H__
#define __RAND_EMBEDDING_ENGINE_H__ 1

#include "lsb/lsb_embedding_engine.h"

#include "lcg.h" // linear congruential generator, a prng

/**
 * @brief implementation of the lsb embedding where random lsb's are taken to
 * hide the data bits
 * @author mnutzinger
 *
 * this class is implemented as a decorator of CLSBEmbeddingEngine in order to
 * not re-implement the lsb stuff and just concentrate on the random stuff as
 * well as the interpretation of the config file (for random seed)
 */
class CRandEmbeddingEngine : public CLSBEmbeddingEngine
{
public:
	CRandEmbeddingEngine(IBitSource* pBitSource);
	virtual ~CRandEmbeddingEngine();

	virtual std::string getIniSectionName() const;

	virtual int embedIntoSamples(int8_t* pSamples, unsigned int pCount, unsigned int pLeak);
	virtual int embedIntoSamples(uint8_t* pSamples, unsigned int pCount, unsigned int pLeak);
	virtual int embedIntoSamples(int16_t* pSamples, unsigned int pCount, unsigned int pLeak);
	virtual int embedIntoSamples(uint16_t* pSamples, unsigned int pCount, unsigned int pLeak);

	virtual int extractFromSamples(int8_t* pSamples, unsigned int pCount, unsigned int pLeak, unsigned int pInBuffer);
	virtual int extractFromSamples(uint8_t* pSamples, unsigned int pCount, unsigned int pLeak, unsigned int pInBuffer);
	virtual int extractFromSamples(int16_t* pSamples, unsigned int pCount, unsigned int pLeak, unsigned int pInBuffer);
	virtual int extractFromSamples(uint16_t* pSamples, unsigned int pCount, unsigned int pLeak, unsigned int pInBuffer);

	virtual int changeSettings();

private:
	CRandEmbeddingEngine();
	CRandEmbeddingEngine(const CRandEmbeddingEngine& );
	CRandEmbeddingEngine& operator=(const CRandEmbeddingEngine& );

	static const std::string sIniSectionName;

	/**
	 * the actual lsb embedding engine which does the embedding work
	 *
	 * @note this object is eventually called in embedIntoSample() and
	 * extractFromSample(), after the prng stuff is done
	 */
	CLSBEmbeddingEngine* mEmbeddingEngine;

	/**
	 * linear congruential generator (prng) object to get random numbers
	 */
	CLcg* mRandom;

	// lcg parameters
	// seed, multiplier, increment and modulo

	unsigned int mSeed;
	unsigned int mMultiplier;
	unsigned int mIncrement;
	unsigned int mModulo;

	// ***************
	// helper function
	// ***************

	bool setProperties();
	void initPrng();
	bool sampleToProcess();
};

#endif // __RAND_EMBEDDING_ENGINE_H__

